-- require "geometry"
local Radome = require "Radome"
local MPIPond=require "MPIPond"
local nl=require "luaNumeric"
require "luaFDTD3D"

function trace (event, line)
    if GetStopFlag()==true then
        local s = debug.getinfo(2).source
        print( s .. ":" .. line )
	error("Abort by user")
    end
end

function Radome:create_radome()
	 local mat = Geometry.AddMaterial( self.material );
	 self.loaded_shape:material( mat );
	return { self.loaded_shape }
end	

function Radome:create_grabber(  )
	 local cm = Geometry.CGLColorMap:new("Jet")
	 local  probe = Geometry.TransientFieldsGrabber:new();
	 probe :name("Grabber-xy("..self.name..")");
	 probe :camera("10019.7 -9708.24 6402.18 -0.4964 -0.205616 -0.322752 -0.779192")
	 -- probe :save2file(true);
	 probe :frame_delay(10);
	 probe :size(2000,1600);
	 probe :add_slice(cm,scalar_e,xy,0,1,false)
	 -- probe :add_slice(cm,ez,yz,0,2)
	  -- probe :is_fill(false);
	 -- probe:fields_types(ez,hx)
	 probe :stride(30);
	 Geometry.AddTransientFieldsGrabber(probe)
	----------------------------
end

--创建天线罩计算池
local RadomePond = MPIPond:new(
	{
		path = ' ';
		name = 'radome';
		num_threads = 12;
		max_steps = 10000;
		max_convergency = -35;
		dext = 20;                                    -- 物体到空气盒子的距离6mm
		boundary = { xm=UPML; };
		units = { freq = GHz; dim = mm };
		mesh_freq = 15;         --剖分频率
		
		
		scan_angles = {0,10};
		beam_types = {'SUM','DIFF' };
		polars = {'HH','VV'};
		
		farbox_info = { freq=probe_freq; 
				       dfarbox = 10; --近场到远场的变换盒子
				       };
		source_info = { freq_min = 5; freq_max = 6;  dsrc  = 2;  --dsrc：源离盒子边界的位置    theta是源的指向角    等效的线源
					posx_antenna = 100;  --天线位置，天线的绝对位置，假设天线放在x轴上
					theta_antenna = 10;           --天线与x轴夹角，天线口面与x轴夹角
					type = "SUM";                     --和波束，DIFF是差波束
					polarization = "HH";            --极化，有交叉极化，罩子的耦合比较小，-20dB左右
					theta_beam = 20;             --天线指向，天线自身的偏转
					wsrc = 100;};                    --天线口面半径， 实际的天线口面直径
		
	}
) 

----------------------------------------------------------------------------------------------------------------------------------------
--GUI交互函数
function RadomePond:update_parameters_to_ui()
end

function RadomePond:update_parameters_from_ui()
end
----------------------------------------------------------------------------------------------------------------------------------------

function RadomePond:set_parameters(
			path,
			m_minAngle,m_maxAngle,m_numAngle,
			m_epsr,m_tans,
			m_minFreq,m_maxFreq,m_numFreq,
			m_meshFreq,
			m_ant_posx,
			m_wsrc,
			m_maxSteps,
			m_convergency,
			m_polarHH,
			m_polarVV,
			m_typeSum,
			m_typeDiff,
			m_calAir
				)
	
		self.radome_path = path;
		
		self.scan_angles = nl.LinearSpace(m_minAngle,m_maxAngle,m_numAngle);
		self.epsr = m_epsr;
		self.tans = m_tans;
		self.minFreq = m_minFreq;
		self.maxFreq = m_maxFreq;
		self.farbox_info.probe_freq = nl.LinearSpace(m_minFreq,m_maxFreq,m_numFreq);
		self.source_info.minFreq = m_minFreq*0.8;
		self.source_info.maxFreq = m_maxFreq*1.2;
		self.meshFreq = m_meshFreq;
		self.source_info.posx_antenna = m_ant_posx;
		self.source_info.wsrc = m_wsrc;
		self.maxSteps = m_maxSteps;
		self.convergency = m_convergency;
		
		if m_polarHH==true then
			self.polars = "HH";
		end
		if m_polarVV==true then
			self.polars  = "VV";
		end
		if m_polarHH==true and m_polarVV==true then
			self.polars  = "ALL";
		end

		if m_typeSum==true then
			self.beam_types = {"SUM"};
		end
		if m_typeDiff==true then
			self.beam_types  = {"DIFF"};
		end
		if m_typeSum==true and m_typeDiff==true then
			self.beam_types  = {"SUM","DIFF"};
		end
end

function RadomePond:create_geometry()

	Geometry.clear_all();
	
	self:update_parameters_from_ui();
	
	local ufreq = Geometry.ref_units_freq();
	---------------------------
	--Materials：天线罩材料（外罩）
	self.material = Geometry.NewDebyeMaterial("材料")  --deby指的是色散模型
	self.material:fill_color(0.5,0.5,0)
	self.material:fit_tangent_delta_e(ufreq*(self.minFreq+self.maxFreq)/2.0,self.epsr,self.tans)
	-------------------------	
	
	---------------------------	
	--导入天线罩模型（外罩）：stp
	local w2 = Geometry.load_step({path = self.radome_path })
	w2:name( "天线罩" )
	w2:fill_color(0.6,0,0.8)
	w2:triangulate(1)
	w2:material( self.material )
	w2:soft_edge();
	self.loaded_shape = w2;
	Geometry.AddShape(self.loaded_shape)
	--------------------------- 
	

	self:perspective_view();
	
	self:clear_results();
	
	self.model = {};
	self.model_runned = {};
	self.model_unrunned = {};
	
	self:create_pond()

end

function RadomePond:create_pond()

	Geometry.set_path(self.radome_path);
	
	self.model = {};
	self.model_runned = {};
	self.model_unrunned = {};
	
	assert( self.material, ' material is invalid ' )
	assert( self.loaded_shape, ' invalid shape' );
	--天线的扫描角
	local angs = self.scan_angles;
	
	print(angs)

	for _,ang in pairs(angs) do
		local ra = Radome:new( { 
					name = self.name.."-ang("..ang..")";
					path = self.radome_path;
					num_threads = self.num_threads;                      --计算的线程数（一般设置为PC的逻辑处理器个数）
					dext = self.dext;                                    -- 物体到空气盒子的距离6mm
					max_steps  = self.maxSteps;
					max_convergency = self.convergency;
					epsr = self.epsr;
					tans = self.tans;
					scan_angle = ang;
					--远场设置
					farbox_info = { freq=self.farbox_info.probe_freq; 
							       dfarbox = self.farbox_info.dfarbox; --近场到远场的变换盒子
							       angle = { start=180-ang-180, stop = 180-ang+180, steps = 721;}  --参数的设置
							       };
							       
					--源设置					       
					source_info = { freq_min = self.source_info.minFreq; 
								freq_max = self.source_info.maxFreq;
								dsrc  = self.source_info.dsrc;  --dsrc：源离盒子边界的位置    theta是源的指向角    等效的线源
								posx_antenna = self.source_info.posx_antenna;  --天线位置，天线的绝对位置，假设天线放在x轴上
								theta_antenna = ang;           --天线与x轴夹角，天线口面与x轴夹角
								type = "SUM";                     --和波束，DIFF是差波束
								polarization = polar;            --极化，有交叉极化，罩子的耦合比较小，-20dB左右
								theta_beam = ang;             --天线指向，天线自身的偏转
								wsrc = self.source_info.wsrc;};                    --天线口面半径， 实际的天线口面直径
					boundary = self.boundary;
					units = self.units;
					mesh_freq = self.meshFreq;         --剖分频率
					farfieldView = self.farfieldView;
					material = self.material;
					loaded_shape = self.loaded_shape;
					} )
		  table.insert( self.model, ra );
	end	
end

function RadomePond:run_pond()

	debug.sethook(trace, "l")

	self:create_pond()
	-- self:clear_results();
	self:find_results()

	print( #self.model )

	self:run()
	-- self:test()
	
	debug.sethook()
end

function RadomePond:run_model_post()
	
	self.xx = nl.new_vector();
	self.yys = {};
	local nf = #self.farbox_info.probe_freq;
	local freq = self.farbox_info.probe_freq;
	for ii=1,nf do
	    self.yys[ii] = { {data=nl.new_vector(),label = "Freq="..freq[ii].."[GHz]-HH"},
	                          {data=nl.new_vector(),label = "Freq="..freq[ii].."[GHz]-VV"} 
				  };
	end
	
	
	for k,model in pairs( self.model_runned ) do
		self.xx:add( model.scan_angle )
		for ii=1,nf do			
			self.yys[ii][1].data:add( model.results.trans.data[ii] )			
		end		
	end
	
		
	if self.tranView == nil then return; end
	
	self:init_trans_plot();
	
	self.tranView:clearGraphs();
	
	for ii=1,nf do	     
		self.tranView:addGraph(self.xx,self.yys[ii][1].data, self.yys[ii][1].label)	    	   
	end
	
	
	self.tranView:rescaleAxes();
	
end

function RadomePond:init_trans_plot()
	 self.tranView.xAxis:setProperty( {name="扫描角度 φ [°]"} )
	 self.tranView.yAxis:setProperty( {name="透过率 [%]"} )
	 self.tranView:rescaleAxes();
end

return RadomePond;
